home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Camelot / Camelot 059 (1989-12)(Swedish User Group of Amiga)(SE)(PD)[WB].zip / Camelot 059 (1989-12)(Swedish User Group of Amiga)(SE)(PD)[WB].adf / Utils / tail.c < prev    next >
C/C++ Source or Header  |  1989-11-14  |  3KB  |  171 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <ctype.h>
  5.  
  6. #define BUG
  7. #define LINESIZE 256
  8. #define FALSE 0
  9. #define TRUE 1
  10.  
  11. FILE *in;
  12. long nb = 10;
  13. int charmode = FALSE;
  14. int keeplast = TRUE;
  15.  
  16. void charnofirst()
  17. {
  18.     int c;
  19.  
  20.     while (--nb > 0 && getc(in) != EOF) ;
  21.  
  22.     while ((c = getc(in)) != EOF && putchar(c) != EOF) ;
  23. }
  24.  
  25. void linenofirst()
  26. {
  27.     char buf[LINESIZE + 1]; /* Ensure NULL byte at end ... */
  28.  
  29.     while (--nb > 0 && fgets(buf, LINESIZE, in)) ;
  30.  
  31.     while (fgets(buf, LINESIZE, in) && fputs(buf, stdout) == 0) ;
  32. }
  33.  
  34. void charlast()
  35. {
  36.     char *buf;
  37.     int buffull;
  38.     long readsize;
  39.  
  40.     buf = malloc(nb);
  41.     if (!buf)
  42.     {
  43.         fputs("No memory !\n", stderr);
  44.         exit(10);
  45.     }
  46.  
  47.     buffull = FALSE;
  48.  
  49.     while ((readsize = fread(buf, 1, nb, in)) == nb) buffull = TRUE;
  50.  
  51.     if (buffull) if (!fwrite(buf + readsize, nb - readsize, 1, stdout)) return;
  52.      
  53.     fwrite(buf, readsize, 1, stdout);
  54. }
  55.  
  56. void linelast()
  57. {
  58.     typedef char LINEBUF[LINESIZE + 1];
  59.     LINEBUF *buf, *bufpos, *bufend, *scanbuf;
  60.     int buffull;
  61.  
  62. #ifdef BUG
  63.     nb++;
  64. #endif
  65.  
  66.     buf = (LINEBUF *)malloc(nb * (LINESIZE + 1));
  67.     if (!buf)
  68.     {
  69.         fputs("No memory !\n", stderr);
  70.         exit(10);
  71.     }
  72.  
  73.     bufend = buf + nb;
  74.     bufpos = buf; buffull = FALSE;
  75.  
  76.     while (fgets(*bufpos, LINESIZE, in))
  77.     {
  78.         bufpos++;
  79.         if (bufpos == bufend)
  80.         {
  81.             bufpos = buf;
  82.             buffull = TRUE;
  83.         }
  84.     }
  85.  
  86.  
  87.     if (buffull)
  88.        for (scanbuf = bufpos; scanbuf != bufend; scanbuf++)
  89.             if (fputs(*scanbuf, stdout) != 0) return;
  90.  
  91.     for (scanbuf = buf; scanbuf != bufpos; scanbuf++)
  92.         if (fputs(*scanbuf, stdout) != 0) return;
  93. }
  94.  
  95. /*
  96.  +nb<l/c>
  97.  -nb<l/c>
  98.  -l/c
  99. */
  100.  
  101. int analyse_opts(opt)
  102. char *opt;
  103. {
  104.     if (opt[0] != '+' && opt[0] != '-') return(FALSE);
  105.  
  106.     if (opt[0] == '+')
  107.     {
  108.         int l;
  109.  
  110.         l = stcd_l(++opt, &nb);
  111.         if (l == 0) return(FALSE);
  112.         opt += l;
  113.         keeplast = FALSE;
  114.     }
  115.     else
  116.         if (isdigit(*++opt)) opt += stcd_l(opt, &nb);
  117.  
  118.     if (opt[0] == 'l') opt++;
  119.     else if (opt[0] == 'c') { charmode = TRUE; opt++; }
  120.  
  121.     return(opt[0] == '\0');
  122. }
  123.  
  124. void main(argc, argv)
  125. int argc;
  126. char **argv;
  127. {
  128.     int usage = TRUE;
  129.  
  130.     if (argc == 1)
  131.     {
  132.         in = stdin;
  133.         usage = TRUE;
  134.     }
  135.     else if (argc == 2)
  136.     {
  137.         in = stdin;
  138.         usage = analyse_opts(argv[1]);
  139.     }
  140.     else if (argc == 3)
  141.     {
  142.         if (usage = analyse_opts(argv[1]))
  143.         {
  144.             in = fopen(argv[2], "r");
  145.             if (!in)
  146.             {
  147.                 fputs("Couldn't open file\n", stderr);
  148.                 exit(10);
  149.             }
  150.         }
  151.     }
  152.     else usage = FALSE;
  153.  
  154.     if (!usage)
  155.         fputs("Usage: tail [+/-number][l/c] [file]\n", stderr);
  156.     else
  157.     {
  158.         if (charmode)
  159.             if (keeplast)
  160.                 charlast();
  161.             else
  162.                 charnofirst();
  163.         else
  164.             if (keeplast)
  165.                 linelast();
  166.             else
  167.                 linenofirst();
  168.     }
  169. }
  170.  
  171.